/**
 */
import java.util.List;
import java.util.Random;
import java.util.ArrayList;

/*
 * A solar system.
 * 
 * @author Michelle Partogi, Araya Zaesim, Stanley Ayzenberg,  Adam Perez
 * @version 1.0
 */

/**
 * @author Araya Zaesim, Stanley Ayzenberg, Michelle Partogi, Adam Perez
 * @version 1.0
 */
public class SolarSystem implements java.io.Serializable {
	/**
	 * Field generator.
	 */
	private static final Random GENERATOR = new Random();

	/**
	 * Field name.
	 */
	private String name;

	/**
	 * Field coordinate.
	 */
	private final Coordinate coordinate;

	/**
	 * Field coordArray.
	 */
	private static List<Coordinate> CoordArray = new ArrayList<Coordinate>();

	/**
	 * Field techLevel.
	 */
	private int techLevel;

	/**
	 * Field resource.
	 */
	private String resource;

	/**
	 * Field size.
	 */
	public String size;

	/**
	 * Field government.
	 */
	private String government;

	/**
	 * Field techLevelName.
	 */
	private String techLevelName;

	/**
	 * Field event.
	 */
	private String event;
	
	/**
	 * Number of goods
	 */
	private static final int NUM_GOODS = 10;
	
	/**
	 * Field goods.
	 */
	private int[] goods = new int[NUM_GOODS];

	/**
	 * Field traderChance.
	 */
	private String traderChance;

	/**
	 * Field pirateChance.
	 */
	private String pirateChance;

	/**
	 * Field policeChance.
	 */
	private String policeChance;
	
	/**
	 * Chance of encounters
	 */
	private static final int ENC_CHANCE = 3;
	
	/**
	 * Chance of events.
	 */
	private static final int EVENT_CHANCE = 8;
	
	/**
	 * Special goods chance
	 */
	private static final int SPEC_CHANCE = 18;
	
	/**
	 * Special goods selector
	 */
	private static final int SPEC_SELECT = 12;
	
	/**
	 * Possible goods
	 */
	private static final int MAX_GOODS = 50;
	
	/**
	 * Extra goods
	 */
	private static final int EXTRA_GOODS = 2;
	
	/**
	 * Water position
	 */
	private static final int WATER_POS = 0;
	
	/**
	 * Furs position
	 */
	private static final int FURS_POS = 1;
	
	/**
	 * Food position
	 */
	private static final int FOOD_POS = 2;
	
	/**
	 * Ore position
	 */
	private static final int ORE_POS = 3;
	
	/**
	 * Games position
	 */
	private static final int GAMES_POS = 4;
	
	/**
	 * Firearms position
	 */
	private static final int FIREARMS_POS = 5;
	
	/**
	 * Medicine position
	 */
	private static final int MEDICINE_POS = 6;
	
	/**
	 * Machines position
	 */
	private static final int MACHINES_POS = 7;
	
	/**
	 * Narcotics position
	 */
	private static final int NARCOTICS_POS = 8;
	
	/**
	 * Robots position
	 */
	private static final int ROBOTS_POS = 9;
	
	/**
	 * Max coordinate position
	 */
	private static final int COORD_MAX = 300;
	
	/**
	 * toString method.
	
	 * @return String */
	public String toString() {
		return "";
	}
	
	/**
	 * Constructor for SolarSystem.
	 * @param name String
	 */
	public SolarSystem(String name) {
		this.name = name;
		this.coordinate = makeCoord(); // Make sure no coordinates are the same
		CoordArray.add(this.coordinate);
		final String[] level = { "Few", "Moderate", "Many" };

		traderChance = level[GENERATOR.nextInt(ENC_CHANCE)];
		pirateChance = level[GENERATOR.nextInt(ENC_CHANCE)];
		policeChance = level[GENERATOR.nextInt(ENC_CHANCE)];

		final String[] govChoice = { "Aristocracy", "Geniocracy", "Kratocracy",
				"Meritocracy", "Technocracy", "Authoritarian", "Autocracy",
				"" + "Dictatorship", "Democracy", "Monarchy", "Bureaucracy",
				"Theocracy", "Ochlocracy", "Anarchy", "Republic" };

		government = govChoice[GENERATOR.nextInt(govChoice.length)];

		// 1 in 10 chance there'll be an event
		techLevel = GENERATOR.nextInt(EVENT_CHANCE); // from 0 to 7

		final String[] resourceChoose = { "Mineral Rich", "Mineral Poor", "Desert",
				"Lots of Water", "Rich Soil", "Poor Soil", "Rich Fauna",
				"Lifeless", "Weird Mushrooms", "Lots of Herbs", "Artistic",
				"Warlike", };
		final int tempInt2 = GENERATOR.nextInt(SPEC_CHANCE);
		if (tempInt2 < SPEC_SELECT) {
			this.resource = resourceChoose[tempInt2];
		} else {
			this.resource = "No Special Resources";
		}

		final String[] sizeChoose = { "Small", "Medium", "Large" };
		this.size = sizeChoose[GENERATOR.nextInt(ENC_CHANCE)];
		populateMarketplace();

	}
	
	/**
	 * Assists in setting up marketplace
	 */
	private void populateMarketplace() {
		if (Goods.WATER.getMTLP() <= techLevel) {
			goods[WATER_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.FURS.getMTLP() <= techLevel) {
			goods[FURS_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.FOOD.getMTLP() <= techLevel) {
			goods[FOOD_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.ORE.getMTLP() <= techLevel) {
			goods[ORE_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.GAMES.getMTLP() <= techLevel) {
			goods[GAMES_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.FIREARMS.getMTLP() <= techLevel) {
			goods[FIREARMS_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.MEDICINE.getMTLP() <= techLevel) {
			goods[MEDICINE_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.MACHINES.getMTLP() <= techLevel) {
			goods[MACHINES_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.NARCOTICS.getMTLP() <= techLevel) {
			goods[NARCOTICS_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
		if (Goods.ROBOTS.getMTLP() <= techLevel) {
			goods[ROBOTS_POS] = GENERATOR.nextInt(MAX_GOODS) + EXTRA_GOODS;
		}
	}

	/**
	 * Method getName.
	
	 * @return String */
	public String getName() {
		return name;
	}

	/*
	 * Get x
	 * 
	 * @return x
	 */
	/**
	 * Method getX.
	
	 * @return int */
	public int getX() {
		return coordinate.x;
	}

	/*
	 * Get y
	 * 
	 * @return y
	 */
	/**
	 * Method getY.
	
	 * @return int */
	public int getY() {
		return coordinate.y;
	}

	/*
	 * Make Coordinate for solar system * If x,y matches another solar system,
	 * change x,y to something else
	 * 
	 * @return Coordinates
	 */
	/**
	 * Method makeCoord.
	
	 * @return Coordinate */
	public Coordinate makeCoord() {
		final int x = GENERATOR.nextInt(COORD_MAX);
		final int y = GENERATOR.nextInt(COORD_MAX);
		Coordinate hello = new Coordinate(x, y);
		for (Coordinate item : CoordArray) {
			if (hello.equals(item)) {
				hello = makeCoord();
				break;
			}
		}
		return hello;
	}

	/**
	 * @author Araya Zaesim, Stanley Ayzenberg, Michelle Partogi, Adam Perez
	 */
	private static class Coordinate implements java.io.Serializable {
		/**
		 * Field x.
		 */
		public int x;

		/**
		 * Field y.
		 */
		public int y;

		/**
		 * Constructor for Coordinate.
		 * @param x int
		 * @param y int
		 */
		private Coordinate(int x, int y) {
			this.x = x;
			this.y = y;
		}
		
		/**
		 * toString method.
		
		 * @return String */
		public String toString() {
			return "";
		}
		
		/*
		 * Sets x in coordinate
		 * 
		 * @param x
		 */
		/**
		 * Method setX.
		 * @param x int
		 */
		public void setX(int x) {
			this.x = x;
		}

		/*
		 * Sets y in coordinate
		 * 
		 * @param y
		 */
		/**
		 * Method setY.
		 * @param y int
		 */
		public void setY(int y) {
			this.y = y;
		}

	}// end coordinate

	/**
	 * Method getTechLevelName.
	
	 * @return String */
	public String getTechLevelName() {
		if (techLevel == 0) {
			techLevelName = "Pre-Agriculture";
		} else if (techLevel == 1) {
			techLevelName = "Agriculture";
		} else if (techLevel == 2) {
			techLevelName = "Medieval";
		} else if (techLevel == 3) {
			techLevelName = "Renaissance";
		} else if (techLevel == 4) {
			techLevelName = "Early Industrial";
		} else if (techLevel == 5) {
			techLevelName = "Industrial";
		} else if (techLevel == 6) {
			techLevelName = "Post-Industrial";
		} else if (techLevel == 7) {
			techLevelName = "Hi-Tech";
		}
		return techLevelName;
	}

	/**
	 * Method getTechLevel.
	
	 * @return int */
	public int getTechLevel() {
		return techLevel;
	}

	/**
	 * Method getResource.
	
	 * @return String */
	public String getResource() {
		return resource;
	}

	/**
	 * Method getGovernment.
	
	 * @return String */
	public String getGovernment() {
		return government;
	}

	/**
	 * Method getEvent.
	
	 * @return String */
	public String getEvent() {
		return event;
	}

	/**
	 * Method getSize.
	
	 * @return String */
	public String getSize() {
		return size;
	}

	/**
	 * Method getDistance.
	 * @param system2 SolarSystem
	
	 * @return float */
	public double getDistance(SolarSystem system2) {
		final double distance = Math
				.sqrt(((coordinate.x - system2.getX()) * (coordinate.x - system2
						.getX()))
						+ ((coordinate.y - system2.getY()) * (coordinate.y - system2
								.getY())));
		return distance;
	}

	/**
	 * Method setGoods.
	 * @param goods int[]
	 */
	public void setGoods(int[] goods) {
		this.goods = goods.clone();
	}

	/**
	 * Method getGoods.
	
	 * @return int[] */
	public int[] getGoods() {
		return goods;
		// MarketPlaceLogic logic = new MarketPlaceLogic(this, null);
		// return logic.buyPrices();
	}

	/**
	 * Method getTraderChance.
	
	 * @return String */
	public String getTraderChance() {
		return traderChance;
	}

	/**
	 * Method getPirateChance.
	
	 * @return String */
	public String getPirateChance() {
		return pirateChance;
	}

	/**
	 * Method getPoliceChance.
	
	 * @return String */
	public String getPoliceChance() {
		return policeChance;
	}

	/**
	 * Method setX.
	 * @param x int
	 */
	public void setX(int x) {
		this.coordinate.setX(x);
	}

	/**
	 * Method setY.
	 * @param y int
	 */
	public void setY(int y) {
		this.coordinate.setY(y);
	}

	/**
	 * Method getCoordArray.
	
	 * @return ArrayList<Coordinate> */
	public static List<Coordinate> getCoordArray() {
		return CoordArray;
	}

	/**
	 * Method setCoordArray.
	 * @param coordArray ArrayList<Coordinate>
	 */
	public static void setCoordArray(List<Coordinate> coordArray) {
		SolarSystem.CoordArray = coordArray;
	}

	/**
	 * Method setName.
	 * @param name String
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Method setTechLevel.
	 * @param techLevel int
	 */
	public void setTechLevel(int techLevel) {
		this.techLevel = techLevel;
	}

	/**
	 * Method setResource.
	 * @param resource String
	 */
	public void setResource(String resource) {
		this.resource = resource;
	}

	/**
	 * Method setGovernment.
	 * @param government String
	 */
	public void setGovernment(String government) {
		this.government = government;
	}

	/*
	 * Set event
	 * 
	 * @param event
	 */
	/**
	 * Method setTechLevelName.
	 * @param techLevelName String
	 */
	public void setTechLevelName(String techLevelName) {
		this.techLevelName = techLevelName;
	}

	/*
	 * Set event
	 * 
	 * @param event
	 */
	/**
	 * Method setEvent.
	 * @param event String
	 */
	public void setEvent(String event) {
		this.event = event;
	}

	/*
	 * Set trader chance
	 * 
	 * @param traderChance
	 */
	/**
	 * Method setTraderChance.
	 * @param traderChance String
	 */
	public void setTraderChance(String traderChance) {
		this.traderChance = traderChance;
	}

	/*
	 * Set pirate chance
	 * 
	 * @param pirateChance
	 */
	/**
	 * Method setPirateChance.
	 * @param pirateChance String
	 */
	public void setPirateChance(String pirateChance) {
		this.pirateChance = pirateChance;
	}

	/*
	 * Set police chance
	 * 
	 * @param policeChance
	 */
	/**
	 * Method setPoliceChance.
	 * @param policeChance String
	 */
	public void setPoliceChance(String policeChance) {
		this.policeChance = policeChance;
	}

}
